package com.heimdallr.app.main.web;


import com.google.code.kaptcha.servlet.KaptchaExtend;
import com.heimdallr.util.AppUtils;
import com.heimdallr.util.RedisKey;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.concurrent.TimeUnit;


/**
 * @author user
 */
@Controller
public class MainController extends KaptchaExtend {

	@Autowired
	private StringRedisTemplate redisTemplate;

    private static final Logger logger = LoggerFactory.getLogger(MainController.class);

    @RequestMapping(value = "/login")
    public String login() {

        Subject user = SecurityUtils.getSubject();

        if(user.isAuthenticated()){
            return  "redirect:/user/index";
        }else{
            return  "login";
        }
    }

    @RequestMapping(value="/logon",produces="application/json;charset=UTF-8",method= RequestMethod.POST)
    public @ResponseBody
    String logon(@RequestParam String userId,
                 @RequestParam String password,
                 @RequestParam(required = false) String captcha,
                 @RequestParam String uuid,
                 HttpServletRequest request){

        String sessionId = request.getSession().getId();

        if(AppUtils.isNotNull(uuid)){
            String kaptcha = (String) request.getSession().getAttribute(uuid);
            if(AppUtils.isNull(kaptcha)||!kaptcha.equals(captcha)){
                return "5";
            }
        }

        try {
            password = AppUtils.md5Encode(AppUtils.md5Encode(password));
        } catch (Exception e) {
            logger.error("密码转换MD5失败！密码为：" + password, e);
        }

        Subject user = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(userId, password);

        try {
            user.login(token);
            token.setRememberMe(true);
            if(redisTemplate.hasKey(RedisKey.loginSession.name()+"-"+userId)){
                String oldSessionId = redisTemplate.opsForValue().get(RedisKey.loginSession.name()+"-"+userId);
                if(AppUtils.isNotNull(oldSessionId)&&!oldSessionId.equals(sessionId)){
                    redisTemplate.delete(oldSessionId);
                }
            }
            redisTemplate.opsForValue().set(RedisKey.loginSession.name()+"-"+userId,sessionId,2, TimeUnit.HOURS);
            return "1";
        } catch (UnknownAccountException e1){
            token.clear();
            return "2";
        }catch (LockedAccountException e2){
            token.clear();
            return "3";
        }catch (Exception e) {
            token.clear();
            return "4";
        }

    }

    //@RequiresRoles("admin")
    @RequestMapping(value = "/signOut")
    public String signOut(){

        Subject subject = SecurityUtils.getSubject();
        subject.logout();

        try{
            subject.getSession().removeAttribute("currentUser");
        }catch (Exception ignored){}
        return "/index";
    }

    @RequestMapping(value = "/unauthorized")
    public String unauthorized()  {
        return "/error/404";
    }

    @RequestMapping(value = "/welcome")
    public String welcome()  {
        return "welcome";
    }

    @RequestMapping(value="/captcha")
    public void  getCaptcha(HttpServletRequest request,
                            HttpServletResponse response) throws ServletException, IOException {

        String uuid = request.getParameter("uuid");
        super.captcha(request,response);
        String  captcha =  getGeneratedKey(request);
        //到时候分布式就放到redis或者memcached
        request.getSession().removeAttribute("KAPTCHA_SESSION_KEY");
        request.getSession().setAttribute(uuid,captcha);

    }


    @RequestMapping(value="/404")
    public String error400(){
        return "/error/404";
    }



}
